VisualHMI - 系统回调函数

本章节主要介绍常用的系统回调函数,常用函数如下所示:

  1. 初始化函数:on_init()
  2. 系统周期回调函数:on_run(screen)
  3. 触摸回调函数:on_press(state,x,y)
  4. 变量修改回调函数:on_update(slave,vtype,addr)
  5. 切换画面回调函数:on_screen_change(screen)

系统函数一览表:

系统回调函数 描述 示例说明
on_init() 初始化 VisualHMI - 系统回调(点击跳转)
on_run(screen) 周期循环 VisualHMI - 系统回调(点击跳转)
on_press(state,x,y) 触摸回调 VisualHMI - 系统回调(点击跳转)
on_update(slave,vtype,addr) 变量修改 VisualHMI - 系统回调(点击跳转)
on_screen_change(screen) 切换画面 VisualHMI - 系统回调(点击跳转)
on_usb_inserted(driver)/on_usb_removed() U盘回调 VisualHMI - 文件IO(点击跳转)
on_sd_inserted(dir)/on_sd_removed() SD卡回调 VisualHMI - 文件IO(点击跳转)
on_copy_file_process(status,filesize,transfersize) 文件拷贝 VisualHMI - 文件IO(点击跳转)
on_draw(screen) 自绘回调 VisualHMI - 自绘(点击跳转)
on_timer(timer_id) 定时器 VisualHMI - 定时器(点击跳转)
on_parse_warning(id, text) 告警回调 VisualHMI - 告警说明(点击跳转)
on_uart_recv(ch,packet) 串口回调 VisualHMI - 自定义串口协议(点击跳转)

适用范围:VisualHMI - HMI&M系列

例程下载链接:ViusalHMI - 系统回调函数(点击下载)

1.on_init() 初始化

系统上电加载 LUA 脚本文件之后,立即调用此回调函数, 通常用于执行初始化操作,仅执行一次

1.1. 加载其他lua文件

当项目的代码复杂,代码量也多,分多个Lua文件时,需要在初始化时候调用加载:

--初始化函数
function on_init()
    dofile('sysParam.lua')
end

1.2. 加载系统参数

系统参数,如SysCfg0触摸音、语言SysLang、音频音量大小SysSndVol、背光设置、用户密码、分期使用参数;

function on_init()
    set_uint16(VT_LW, 0x011B, (1<<1)) -- 选择需要加载的掩码,bit1,多语言
    --若有多个系统参数掉电存储加载,则或运算多个位掩码
    --set_uint16(VT_LW, regAddr.sysParamSlct, (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0))
    set_uint16(VT_LW, regAddr.sysParamCtrl, 0x5501)
    update_system()
end

function on_update(slave,vtype,addr)
    if vtype == VT_LW
    then
        if addr == 0x119
        then
            set_uint16(VT_LW, 0x011B, (1<<1)) -- 选择需要加载的掩码,bit1,多语言
            set_uint16(VT_LW, 0x011A, 0x5501) -- 保存选中的系统参数
            update_system()
        end
    end
end

1.3. 初始化Flash参数

屏幕内部有64K用户掉电存储空间,RW0000~RW7FFFF(一个地址2个字节,共64K),屏幕flash新片,默认均为0xFF。实际应用中,通常设备第一次使用,需要初始化一些参数,可以通过判断Flash值,当不等于某个特定数值,执行相关初始化操作,如下所示:

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_init()
    local fst = get_uint16(VT_RW, 0x7FFF)
    if fst ~= 0x55AA
    then
        set_uint16(VT_LW, regAddr.sysCfg0, 1)
        set_uint16(VT_LW, regAddr.sysLang, 0)
        set_uint16(VT_LW, regAddr.sysBLLevel, 100)
        set_uint16(VT_LW, regAddr.sysSndVol, 80)

        set_uint16(VT_LW, regAddr.sysParamSlct, (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0))
        set_uint16(VT_LW, regAddr.sysParamCtrl, 0x5501)
        update_system()
        set_uint16(VT_RW, 0x7FFF, 0x55AA)
    end
end

1.4. 初始化PLC/ 驱动板

屏幕上电,可以往PLC/ 驱动板发送指令,初始化参数,如下所示

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_init()
    set_uint16(VT_4x,0x0000, 0x55AA)
    set_bit(VT_0x,0x1000, 0x0001)
end

2.on_run(screen) 周期回调函数

on_run(screen) 系统周期回调函数

  • screen:当前画面

可以通过set_run_cycle(cycle) API 设置 on_run 的回调周期,毫秒单位

  • cycle:单位ms

[!note|tip:注意] 不要在on_run 里面调用set_run_cycle(cycle)

如在on_run里面不断检测当前电压,和目标电压值,

ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_run(screen)
    local start  = get_uint16(VT_4x, 0x1000) --开机状态
    local dstVol = get_uint16(VT_4x, 0x1001) --设置电压
    local curVol = get_uint16(VT_4x, 0x1002) --当前电压
    local online = get_uint16(VT_4x, 0x01A3) --在线状态,位掩码
    if dstVol > curVol and start == 1 and (online&0x01 == 1)--设备开启后,且从机在线,当前电压不等于目标电压,设置当前电压值
    then
        set_uint16(VT_4x, 0x1003, 1) --设置频率
    end
end

function on_init()
    set_run_cycle(1000) --on_run(screen)  1s回调一次
end

3. on_press(state,x,y) 触摸回调函数

触摸回调函数,当带触摸的串口屏,点击屏幕会触发回调该函数(100ms回调一次)

  • state: 0-弹起、1-按下、2-长按
  • x:按下时X轴坐标
  • y:按下时Y轴坐标

触摸回调函数常用于做自定义待机逻辑,搭配on_timer实现 “屏幕空闲时间(无触摸)到达后,自动进入节能状态”

_ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10    --线圈
VT_1x = 11    --输入点
VT_3x = 12    --输入寄存器
VT_4x = 13    --保持寄存器

_EN_ON_UPDATA_API_  = 1

function on_init()
    _EN_ON_UPDATA_API_ = 0

    dofile('std.lua')
    std.init()

    _EN_ON_UPDATA_API_ = 1
end

--触摸回调
function on_press(state,x,y)
    _EN_ON_UPDATA_API_ = 0

    if state == 0
    then
        std.init()
    end

    _EN_ON_UPDATA_API_ = 1  
end

--修改变量
function on_update(slave,vtype,addr)
    if _EN_ON_UPDATA_API_ == 0
    then
        return  
    end

    std.set(slave,vtype,addr)
end

--定时器回调
function on_timer(timer_id)
   std.notify(timer_id)
end
--std.lua
std = {}
std.cnt = 0

--待机初始化
function std.init()
    local fst = get_uint16(VT_RW, 0x7FFF)
    if fst ~= 0x55AA
    then
        set_uint16(VT_RW, 0x7FFF, 0x55AA) 
        set_uint16(VT_RW, 0x1011, 3)--待机时间
        set_uint16(VT_RW, 0x1012, 3)--屏保时间
        set_uint16(VT_RW, 0x1013, 100)--激活亮度
    end

    local screenSaveTimer  = get_uint16(VT_RW, 0x1011)*60
    local standbyTimer = get_uint16(VT_RW, 0x1012)*60
    local bk = get_uint16(VT_RW, 0x1013)

    set_uint16(VT_LW, 0x0121, bk)

    std.cnt = 0
    stop_timer(_01_standby)
    if lastAlarmStatus == 1
    then
        return
    end
    start_timer(_01_standby, 1000 ,1 ,(screenSaveTimer + standbyTimer))
end

--待机通知,定时器里调用
function std.notify(timer_id)
    if _01_standby == timer_id
    then
        std.cnt = std.cnt + 1

        local screenSaveTimer  = get_uint16(VT_RW, 0x1011)*60
        local standbyTimer = get_uint16(VT_RW, 0x1012)*60

        if std.cnt == screenSaveTimer --屏保时间
        then
            set_screen(__page.home)

        elseif std.cnt == (screenSaveTimer + standbyTimer)--待机时间
        then
            set_uint16(VT_LW, 0x0121, 0)
            set_screen(__page.std)
        end
    end
end

--待机时间设置
function std.set(slave,vtype,addr)
    if vtype == VT_RW
    then
        if addr >= 0x1011 and addr <= 0x1014
        then
            std.init()
        end
    end
end

4. update_system(slave,vtype,addr)

变量被设置后,自动执行此函数

  • slave:站号索引,0开始
  • vtype:变量类型,生成main.lua,自动定义变量的数据类型
  • addr:变量地址

[!note|tip:注意] 1.串口指令修改寄存器值,不会触发on_update回调

2.在on_update函数里,调用set_uit16(set_int16/set_uint32...), 不会在触发on_update回调

3.在其他系统回调函数,如on_init ,执行set_uit16(set_int16/set_uint32...) ,会触发on_update回调

4.用户点击屏幕,修改控件状态(寄存器值),会触发on_update回调

如下所示,已Modbus 协议为例,当其他回调函数设置寄存器,均不想触发on_update回调,可以定义全局变量如下处理:

ENCRYPT_=0    --LUA脚本加密

EN_ON_UPDATE_API_CB = 1 --全局变量,其他回调函数设置寄存器时,为1执行,为0直接退出

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10   --线圈
VT_1x = 11   --输入点
VT_3x = 12   --输入寄存器
VT_4x = 13   --保持寄存器

function on_init()
    EN_ON_UPDATE_API_CB = 0

    --user code
    set_uint16(VT_LW, 0x10000x55AA)

    EN_ON_UPDATE_API_CB = 1
end

function on_run(screen)
    EN_ON_UPDATE_API_CB = 0
    --user code
    EN_ON_UPDATE_API_CB = 1
end

function on_update(slave, vtype, addr)
    if EN_ON_UPDATE_API_CB == 0
    then
        return
    end

    if slave == 0
    then
        if vtype == VT_4x --保持寄存器
        then
            if addr == 0x1000
            then
                local val = get_uint16(VT_4x, addr)   
                if val == 1
                then
                    set_uint16(VT_4x, 0x0001, val) 
                end
            end
        elseif vtype == VT_0x --线圈
        then
            if addr == 0x0000
            then
                local val = get_uint16(VT_0x, addr)
                if val == 1
                then
                    set_uint16(VT_0x, 0x0001, val) 
                end
            end
        end
    end

    if vtype == VT_LW --内部寄存器
    then
        if addr == 0x1000
        then
            local val = get_uint16(VT_LW, addr)
            if 0x55AA == val
            then
                 set_uint16(VT_4x, 0x0000, val)  
            end
        end
    end
end

function on_draw(screen_id,control_id)
    EN_ON_UPDATE_API_CB = 0

    --user code

    EN_ON_UPDATE_API_CB = 1
end

function on_screen_change(screen)
    EN_ON_UPDATE_API_CB = 0

    --user code
    if screen == 1
    then
        set_bit(VT_0x, 0x0000, 1)
    end

    EN_ON_UPDATE_API_CB = 1
end

5. on_screen_change(screen)

画面切换通知

  • screen:切换后的画面ID

[!note|tip:注意]

注意:以下情况不会触发on_screen_change

1.切换功能按钮打开对话框/set_uint16(VT_LW, SysDialog)/show_dialog,不会触发回调,如画面A,切到对话框B,screen 仍为画面A

2.在on_screen_change回调里,调用set_screen/set_uint16(VT_LW, SysScreen)

Copyright ©Dacai all right reserved,powered by Gitbook该文件修订时间: 2024-01-16 08:32:32

results matching ""

    No results matching ""